/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "utils_noncopyable.h"
#include "utils_buffer.h"
#include "common_media_define.h"
#include <functional>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>

namespace El {
namespace Media {

/// 音频帧、视频帧
class MediaFrame {
    DISALLOW_COPY_AND_MOVE(MediaFrame);

public:
    MediaFrame() = default;
    ~MediaFrame();

    /// 设置帧的大小，使用前必须要设置大小
    /// \param size 帧的大小
    bool SetSize(int32_t size);

    /// 设置帧数据
    bool PutBuffer(const uint8_t *data, int32_t length);

    //// 获取包缓冲区起始位置指针
    uint8_t *GetBuffer() const;

    //// 获取有效数据长度
    int32_t GetLength() const;

    /// 设置通道号
    void SetChannel(int32_t channel);

    /// 获取帧通道号
    int32_t GetChannel() const;

    /// 设置帧类型
    void SetFrameType(uint32_t type);

    /// 获取帧类型
    uint32_t GetFrameType() const;

    /// 设置pts时间,单位微秒
    void SetPts(uint64_t pts);

    /// 获取pts时间，单位微秒
    uint64_t GetPts() const;

    /// 设置UTC时间,单位微秒
    void SetUtc(uint64_t utc);

    /// 获取UTC时间，单位微秒
    uint64_t GetUtc() const;

    /// 设置帧序号
    void SetSeq(uint32_t seq);

    /// 获取帧序号
    uint32_t GetSeq() const;

    /// 设置编码类型
    void SetCodecType(uint32_t type);

    /// 获取编码类型
    uint32_t GetCodecType() const;

    /// 设置帧率
    void SetFrameRate(double frame_rate);

    /// 获取帧率
    double GetFrameRate() const;

    /// 是否是视频帧
    bool IsVideoFrame() const;

    /// 是否是音频帧
    bool IsAudioFrame() const;

    /**
     * @brief 获取帧信息
     * @return 帧信息字符串
     */
    std::string ToString() const;

private:
    int32_t ch_{0};
    uint32_t type_{MEDIA_FRAME_UNKOWN};
    uint64_t pts_{0};
    uint64_t utc_{0};
    uint32_t seq_{0};
    uint32_t codec_type_{MEDIA_VIDEO_CODEC_UNKOWN};
    double frame_rate_{0};

    void *poolData_{nullptr};  // 从内存池分配的数据指针
    uint32_t poolDataSize_{0}; // 从内存池分配的数据大小
    uint32_t usedSize_{0};     // 实际使用的数据大小
};

using MediaFramePtr = std::shared_ptr<MediaFrame>;

} // namespace Media
} // namespace El